package github.labuladong;

/**
 * @Author: DRevelation
 * @Date: 2020/12/14 15:36
 * 斐波那契数列
 */
public class Fib {

    /**
     * 低效
     * 重复计算 f(20)=f(19)+f(18)  f(19)=f(18)+f(17)
     * 时间复杂度 O(2^n)
     * @param n
     * @return
     */
    private static int fib(int n) {
        if (n == 1 || n == 2) {
            return 1;
        } else {
            return fib(n - 1) + fib(n - 2);
        }
    }

    /**
     * 用数组存放计算过的数据
     * 时间复杂度 O(n)
     * @param n
     * @return
     */
    private static int fib2(int n) {
        int[] dp = new int[n + 1];
        dp[1] = dp[2] = 1;
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }

    /**
     * 对fib2的优化，空间复杂度降为 O(1)
     * @param n
     * @return
     */
    private static int fib3(int n) {
        if (n == 1 || n == 2) {
            return 1;
        }
        int prev = 1, curr = 1;
        for (int i = 3; i <= n; i++) {
            int sum = prev + curr;
            prev = curr;
            curr = sum;
        }
        return curr;
    }

    public static void main(String[] args) {
        System.out.println("fib(10) = " + fib(10));
        System.out.println("fib2(10) = " + fib2(10));
        System.out.println("fib3(10) = " + fib3(10));
    }

}
